using Moq;
using Myotragus.Data.Containers;
using Myotragus.Data.Criteria;
using Myotragus.Data.Repositories;
using Myotragus.Data.Tests.Domain;
using NHibernate;
using NUnit.Framework;

namespace Myotragus.Data.Tests.Tests.Repository
{
	[TestFixture]
	public class LocalizableRepositoryFixtures
	{
		[Test]
		public void FindAndCountAll()
		{
			var entities = new Mock<IEntitiesContainer>();
			var queryBuilder = new Mock<ILocalizableQueryBuilder<ITestEntity>>();
			var result = new Mock<ITestEntity>();
			var resultType = result.Object.GetType();
			var criteria = new Mock<ICriteria>().Object;
			var query = new Mock<IPagedQuery<ITestEntity>>().Object;

			const int lcId = 101;
			const int count = 10;

			entities.Setup(m => m.ResolveType(typeof(ITestEntity))).Returns(resultType);

			queryBuilder.Setup(m => m.CreateCriteria(lcId)).Returns(criteria);
			queryBuilder.Setup(m => m.CreateQuery<ITestEntity>(criteria)).Returns(query);
			queryBuilder.Setup(m => m.Count(criteria)).Returns(count);

			var repo = new LocalizableReadRepository<ITestEntity>(entities.Object, queryBuilder.Object);
			Assert.AreEqual(query, repo.FindAll(lcId));
			Assert.AreEqual(count, repo.CountAll(lcId));

			queryBuilder.VerifyAll();
			entities.VerifyAll();
		}

		[Test]
		public void FindAndCountMatching()
		{
			var entities = new Mock<IEntitiesContainer>();
			var queryBuilder = new Mock<ILocalizableQueryBuilder<ITestEntity>>();
			var result = new Mock<ITestEntity>();
			var resultType = result.Object.GetType();
			var criteria = new Mock<ICriteria>().Object;
			var query = new Mock<IPagedQuery<ITestEntity>>().Object;
			var pattern = new { T1 = 1, T2 = 2 };

			const int lcId = 101;
			const int count = 10;

			entities.Setup(m => m.ResolveType(typeof(ITestEntity))).Returns(resultType);

			queryBuilder.Setup(m => m.CreateMatchingCriteria(lcId, pattern)).Returns(criteria);
			queryBuilder.Setup(m => m.CreateQuery<ITestEntity>(criteria)).Returns(query);
			queryBuilder.Setup(m => m.Count(criteria)).Returns(count);

			var repo = new LocalizableReadRepository<ITestEntity>(entities.Object, queryBuilder.Object);
			Assert.AreEqual(query, repo.FindMatching(lcId, pattern));
			Assert.AreEqual(count, repo.CountMatching(lcId, pattern));

			queryBuilder.VerifyAll();
			entities.VerifyAll();
		}

		[Test]
		public void FindAndCountLike()
		{
			var entities = new Mock<IEntitiesContainer>();
			var queryBuilder = new Mock<ILocalizableQueryBuilder<ITestEntity>>();
			var result = new Mock<ITestEntity>();
			var resultType = result.Object.GetType();
			var criteria = new Mock<ICriteria>().Object;
			var query = new Mock<IPagedQuery<ITestEntity>>().Object;
			var pattern = new { T1 = 1, T2 = 2 };

			const int lcId = 101;
			const int count = 10;

			entities.Setup(m => m.ResolveType(typeof(ITestEntity))).Returns(resultType);

			queryBuilder.Setup(m => m.CreateLikeCriteria(lcId, pattern)).Returns(criteria);
			queryBuilder.Setup(m => m.CreateQuery<ITestEntity>(criteria)).Returns(query);
			queryBuilder.Setup(m => m.Count(criteria)).Returns(count);

			var repo = new LocalizableReadRepository<ITestEntity>(entities.Object, queryBuilder.Object);
			Assert.AreEqual(query, repo.FindLike(lcId, pattern));
			Assert.AreEqual(count, repo.CountLike(lcId, pattern));

			queryBuilder.VerifyAll();
			entities.VerifyAll();
		}
	}
}